import pycpuid
###########################################################################
## Variables Generales
###########################################################################
vendor_string = pycpuid.vendor()
modelo_string = pycpuid.brand_string()
family = pycpuid.family()
stepping = pycpuid.cpuid(0x80000001)[0]

def codename():

###########################################################################
## Variables privadas 0fh, 10h, 11h
###########################################################################

	socket_0fh = (pycpuid.cpuid(0x80000001)[0] >> 0x4) & 0x3
	core = pycpuid.cpuid(0x80000008)[2] & 0xff
	l2_cache_0fh = (pycpuid.cpuid(0x80000006)[1] >> 0x11) & 0x10

	socket_10h = (pycpuid.cpuid(0x80000001)[1] >> 0x1c)
	l3_cache_10h = (pycpuid.cpuid(0x80000006)[3] >> 0x12) & 0xe

	socket_11h = (pycpuid.cpuid(0x80000001)[1] >> 0x1c) & 0x4

###########################################################################
## Opteron/Dual Core Opteron/Athlon64 FX 0fh 
###########################################################################

	if (socket_0fh == 1) \
	and stepping in(0x40f12, 0x40f13, 0x50fd3) \
	and any(modelo in modelo_string for modelo in('AMD Opteron','Dual Core AMD Opteron')):
       		return 'Santa Rosa' ## 2210/2224SE

	if (socket_0fh == 1) \
	and (stepping == 0xc0f13) \
	and ('Athlon(tm) 64 FX' in modelo_string):
       		return 'Windsor' ## FX-70/74

###########################################################################
## Athlon/Athlon64/Sempron 0fh 
###########################################################################
## AM2 Single Core 0fh
###########################################################################

	if (socket_0fh == 3) \
	and stepping in(0x40ff2, 0x50ff2, 0x50ff3) \
	and any(modelo in modelo_string for modelo in('Athlon(tm) 64 Processor', 'Athlon(tm) Processor LE')):
		return 'Orleans' ## Athlon 64 3500-4000
				 ## Athlon LE 1600-1640

	elif (socket_0fh == 3) \
	and stepping in(0x40ff2, 0x50ff2) \
	and ('Sempron(tm) Processor' in modelo_string):
		return 'Manila'	## 64 2800-3800
	
	if (socket_0fh == 3) \
	and (stepping == 0x70ff1) \
	and ('Sempron(tm) Processor LE' in modelo_string):
		return 'Sparta' ## LE 1100-1200

	if (socket_0fh == 3) \
	and (stepping == 0x70ff2) \
	and ('Sempron(tm) Processor LE' in modelo_string):
		return 'Sparta' ## LE 1200-1300

	if (socket_0fh == 3) \
	and (stepping == 0x70ff1) \
	and any(modelo in modelo_string for modelo
	in('Athlon(tm) Processor LE', 'Athlon(tm) Processor 1', 'Athlon(tm) 64 Processor')):
		return 'Lima' ## 2000/2600/3100/3500/3800

	if (socket_0fh == 3) \
	and stepping in(0x70ff2, 0x60ff2) \
	and any(modelo in modelo_string for modelo \
	in('Athlon(tm) Processor LE', 'Athlon(tm) Processor 1', 'Athlon(tm) Processor')):
		return 'Lima' ## LE-1600/40/60
			      ## LE-1640B
			      ## 2650e/3200/3500/3800

###########################################################################		
## AM2 Dual Core OFh
###########################################################################

	if (socket_0fh == 3) \
	and stepping in(0x40f33, 0x40fb2) \
	and any(modelo in modelo_string for modelo in('64 X2 Dual Core', 'Athlon(tm) 64 FX-', 'Athlon(tm) X2 Dual Core')) \
	and (core == 1):
		return 'Windsor' ## FX-62
				 ## 3400/3600/3800/4200/4600/5000	

	if (socket_0fh == 3) \
	and (stepping == 0x40f32) \
	and modeo_string in('Dual-Core AMD Opteron', 'Athlon(tm) X2 Dual Core') \
	and (core == 1):
        	return 'Santa Ana' ## 1210/1224SE
		
	if (socket_0fh == 3) \
	and stepping in(0x60fb1, 0x60fb2) \
	and any(modelo in modelo_string for modelo \
	in('Athlon(tm) X2 Dual Core Processor BE', '64 X2 Dual Core', 'Athlon(tm) Neo X2 Dual Core',
	'Sempron(tm) Dual Core')) \
	and (core == 1):
        	return 'Brisbane' ## 64 X2 3600/6000
				  ## BE-2300/2350/2400/2450
				  ## Neo X2 6850e
				  ## Sempron X2 2100/2300
###########################################################################
## S1G1 0Fh Single Core 0fh
###########################################################################

	if (socket_0fh == 0) \
	and (stepping == 0x40fc2) \
	and any(modelo in modelo_string for modelo in ('Sempron(tm) Processor', 'Mobile AMD Sempron(tm) Processor')):
		return 'Keene' #Mobile Sempron 3200+,3400+,3500+,3600+,3800+
			       #Sempron 2100+

	if (socket_0fh == 0) \
	and stepping in(0x70fc2, 0x60fc2) \
	and any(modelo in modelo_string for modelo in('Athlon(tm) Processor TF', 'Mobile AMD Sempron(tm) Processor')):
		return 'Sherman' #Mobile Sempron 3600+,3800+,4000+
				 #TF-20,36,38

	if (socket_0fh == 0) \
	and (stepping == 0x40fc2) \
	and any(modelo in modelo_string for modelo in('Turion(tm) 64 Mobile Technology MK-')):
		return 'Richmond' ##MK-36,38

###########################################################################		
## S1G1 0Fh Dual Core 0fh
###########################################################################

	if (socket_0fh == 0) \
	and (stepping == 0x40f82) \
	and any(modelo in modelo_string for modelo \
	in('Turion(tm) 64 X2 Mobile Technology TL', 'Athlon(tm) 64 X2 Dual-Core Processor TK')) \
	and (l2_cache_0fh <= 256):
		return 'Taylor' #TL-50,52,56,58,60,62,64
				#TK-55

	if (socket_0fh == 0) \
	and (stepping == 0x40f82) \
	and any(modelo in modelo_string for modelo \
	in('Turion(tm) 64 X2 Mobile Technology TL', 'Athlon(tm) 64 X2 Dual-Core Processor TK')) \
	and (l2_cache_0fh > 256): \
		return 'Trinidad' #TL-52,54,56
				
	if (socket_0fh == 0) \
	and stepping in(0x60f82, 0x60f81) \
	and any(modelo in modelo_string for modelo \
	in('Turion(tm) 64 X2 Mobile Technology TL', 'Athlon(tm) 64 X2 Dual-Core Processor TK', \
	'Sempron(tm) Dual Core Processor T', 'Athlon(tm) X2 Dual Core', 'Athlon(tm) 64 X2 Dual Core')):
		return 'Tyler' ##TL-56,58,60,62,64,66,68
			       ##TK-42,53,55,57

	if (socket_0fh == 0) \
	and (stepping == 0x70fc2) \
	and ('Athlon(tm) Processor L1' in modelo_string): \
		return 0

###########################################################################
## ASB1 0Fh
###########################################################################

	if (socket_0fh == 3) \
	and any(step in stepping for step in(0x70ff2, 0x60ff2)) \
	and ('Athlon(tm) Neo Processor MV' in modelo_string):
		return 'Huron' ## MV-40

	if (socket_0fh == 3) \
	and stepping in(0x70ff2, 0x60ff2, 0x60fb2) \
	and any(modelo in modelo_string for modelo \
	in('Sempron(tm) Processor', 'Sempron(tm) Processor 2', \
	'Turion(tm) Neo X2 Dual Core Processor L6', 'Athlon(tm) Neo X2 Dual Core Processor L3')):
		return 'Congo' ## 200U, 210U, L325, L335, L510, L625

###########################################################################		
###########################################################################
## Familia 10h
###########################################################################
###########################################################################		
###########################################################################
## Opteron 1300/8300 Series 10h
###########################################################################

	if (socket_10h == 1) \
	and stepping in(0x100f22, 0x100f23) \
	and (l3_cache_10h == 4) \
	and ('Opteron' in modelo_string):
       		return 'Budapest' ## 1352/56 Series AM2r2
    
	elif (socket_10h == 1) \
	and (stepping == 0x100f42) \
	and (l3_cache_10h == 12) \
	and ('Opteron' in modelo_string):
		return 'Suzuka' ## 1381/89 Series AM3
    
    	elif (socket_10h == 0) \
	and stepping in(0X100F2A, 0X100F23) \
	and (l3_cache_10h == 4) \
	and ('Opteron' in modelo_string):
       		return 'Barcelona' ## 2347/60 Se Series

    	elif (socket_10h == 0) \
	and (stepping == 0X100F42) \
	and (l3_cache_10h == 12) \
	and ('Opteron' in modelo_string):
       		return 'Shanghai' ## 2375/93 Se Series

	elif (socket_10h == 0) \
	and (stepping == 0X100F80) \
	and (l3_cache_10h == 12) \
	and ('Opteron' in modelo_string):
       		return 'Istambul' ## 2427/2439
				  ## 2419
				  ## 8431/39
				  ## 8425

###########################################################################
## PhenomII/AthlonII/Sempron 140 10h
###########################################################################

	elif (socket_10h == 1) \
	and stepping in(0X100F42, 0X100F43) \
	and l3_cache_10h in(8, 12) \
	and (core == 3) \
	and ('Phenom(tm) II X4' in modelo_string):
       		return 'Deneb' ## 805/965
			       ## B95, B93
			       ## 42 TWKR

    	elif (socket_10h == 1) \
	and (stepping == 0x100f42) \
	and (l3_cache_10h == 12) \
	and (core == 2) \
	and ('Phenom(tm) II X3' in modelo_string):
		return 'Heka' ## 700e/720
			      ## B73, B75    

	elif (socket_10h == 1) \
	and stepping in(0X100F42, 0X100F43) \
	and (l3_cache_10h == 12) \
	and (core == 1) \
	and ('Phenom(tm) II X2' in modelo_string):
       		return 'Callisto' ## 545/550
				  ## B53, B55
    
	elif (socket_10h == 1) \
	and (stepping == 0X100F42) \
	and (l3_cache_10h == 0) \
	and (core == 3) \
	and ('Athlon(tm) II X4' in modelo_string):
	        return 'Propus' ## 600e/630
    
	elif (socket_10h == 1) \
	and (stepping == 0x100f52) \
	and (l3_cache_10h == 0) \
	and (core == 2) \
	and ('Athlon(tm) II X3' in modelo_string):
	        return 'Rana' ## 400e/435

	elif (socket_10h == 1) \
	and stepping in(0x100f52, 0x100f62) \
	and (l3_cache_10h == 0) \
	and (core == 1) \
	and ('Athlon(tm) II X2' in modelo_string):
       		return 'Regor' ## 215/250
			       ## B22, B24

	elif (socket_10h == 1) \
	and (stepping == 0x100f62) \
	and (l3_cache_10h == 0) \
	and (core == 0):
       		return 'Sargas' ## Sempron 140

###########################################################################
## Phenom 10h
###########################################################################
		
	elif (socket_10h == 1) \
	and stepping in(0x100f22, 0x100f23) \
	and (l3_cache_10h == 4) \
	and (core == 3) \
	and ('Phenom(tm)' in modelo_string):
	        return 'Agena' ## 9100e/9950
			       ## 9600B, 9750B
		
	elif (socket_10h == 1) \
	and stepping in(0x100f22, 0x100f23) \
	and (l3_cache_10h == 4) \
	and (core == 2) \
	and ('Phenom(tm)' in modelo_string):
	        return 'Toliman' ## 8250e/8850
				 ## 8600B, 8750B

###########################################################################
## AthlonX2 10h
###########################################################################
		
	elif (socket_10h == 0) \
	and stepping in(0x100f52, 0x100f62) \
	and (l3_cache_10h == 0) \
	and (core == 0):
       		return 'Kuma' ## 6500/7850

###########################################################################
## Sempron Mobile/Turion Ultra/TurionII Ultra 10h
###########################################################################		

	elif (socket_10h == 0) \
	and (stepping == 0x100f62) \
	and (l3_cache_10h == 0) \
	and any(modelo in modelo_string for modelo in('Sempron(tm) M1', 'Athlon(tm) II Dual-Core M3', \
	'Turion(tm) II Ultra Dual-Core Mobile M6', 'Turion(tm) II Dual-Core Mobile M5')):
		return 'Caspian' ## M100, M120
				 ## M300, 320, 340
				 ## M600, M620, M640, M660
				 ## M500, M520, M540

###########################################################################
## Familia 11h
###########################################################################
## Sempron/Athlon Mobile/Turion Ultra Dual-Core/Turion X2 Dual-Core Mobile/
## Athlon X2 Dual-COre/Sempron X2 Dual-Core Mobile
###########################################################################
############################################################################
## Sempron SI/Athlon QI 11h
############################################################################

	if (socket_11h == 2) \
	and (stepping == 0X200F31) \
	and any(modelo in modelo_string for modelo in('Sempron(tm) SI-', 'Athlon(tm) QI-')):
		return 'Sable' ## SI-40,46
			       ## QI-46

	if (socket_11h == 2) \
	and (stepping == 0X200F31) \
	and any(modelo in modelo_string for modelo \
	in('Ultra Dual-Core Mobile ZM-', 'Turion(tm) X2 Dual-Core Mobile RM-', 'Athlon(tm) X2 Dual-Core QL-', 'Sempron(tm) X2 Dual-Core NI-')):
		return 'Lion' ## Turion ZM-80, 87
			      ## RM-70,77
			      ## NI-52
